package com.apigen.platform.service.impl;

import com.apigen.platform.entity.SysUser;
import com.apigen.platform.mapper.SysUserMapper;
import com.apigen.platform.service.ISysUserService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 系统用户服务实现类
 *
 * @author API Generator
 * @since 2024-09-24
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService {

    private final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();

    @Override
    public SysUser getByAccountName(String accountName) {
        if (StringUtils.isBlank(accountName)) {
            return null;
        }
        return baseMapper.selectByAccountName(accountName);
    }

    @Override
    public SysUser getByEmail(String email) {
        if (StringUtils.isBlank(email)) {
            return null;
        }
        return baseMapper.selectByEmail(email);
    }

    @Override
    public SysUser getByPhone(String phone) {
        if (StringUtils.isBlank(phone)) {
            return null;
        }
        return baseMapper.selectByPhone(phone);
    }

    @Override
    public IPage<SysUser> getUserPage(Page<SysUser> page, String accountName, String nickName, String email, Boolean isEnabled) {
        return baseMapper.selectUserPage(page, accountName, nickName, email, isEnabled);
    }

    @Override
    public List<SysUser> getUsersByRoleId(Long roleId) {
        if (roleId == null) {
            return List.of();
        }
        return baseMapper.selectUsersByRoleId(roleId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean createUser(SysUser user) {
        if (user == null || StringUtils.isBlank(user.getAccountName())) {
            return false;
        }

        // 检查账户名是否已存在
        if (existsAccountName(user.getAccountName(), null)) {
            throw new IllegalArgumentException("账户名已存在");
        }

        // 检查邮箱是否已存在
        if (StringUtils.isNotBlank(user.getEmail()) && existsEmail(user.getEmail(), null)) {
            throw new IllegalArgumentException("邮箱已存在");
        }

        // 检查手机号是否已存在
        if (StringUtils.isNotBlank(user.getPhone()) && existsPhone(user.getPhone(), null)) {
            throw new IllegalArgumentException("手机号已存在");
        }

        // 加密密码
        if (StringUtils.isNotBlank(user.getUserPassword())) {
            user.setUserPassword(passwordEncoder.encode(user.getUserPassword()));
        }

        // 设置默认值
        if (user.getIsAdmin() == null) {
            user.setIsAdmin(false);
        }
        if (user.getIsEnabled() == null) {
            user.setIsEnabled(true);
        }
        if (user.getLoginCount() == null) {
            user.setLoginCount(0);
        }
        if (user.getPriority() == null) {
            user.setPriority(0);
        }

        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());

        return save(user);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateUser(SysUser user) {
        if (user == null || user.getUserId() == null) {
            return false;
        }

        SysUser existUser = getById(user.getUserId());
        if (existUser == null) {
            throw new IllegalArgumentException("用户不存在");
        }

        // 检查账户名是否已存在
        if (StringUtils.isNotBlank(user.getAccountName()) && 
            !user.getAccountName().equals(existUser.getAccountName()) && 
            existsAccountName(user.getAccountName(), user.getUserId())) {
            throw new IllegalArgumentException("账户名已存在");
        }

        // 检查邮箱是否已存在
        if (StringUtils.isNotBlank(user.getEmail()) && 
            !user.getEmail().equals(existUser.getEmail()) && 
            existsEmail(user.getEmail(), user.getUserId())) {
            throw new IllegalArgumentException("邮箱已存在");
        }

        // 检查手机号是否已存在
        if (StringUtils.isNotBlank(user.getPhone()) && 
            !user.getPhone().equals(existUser.getPhone()) && 
            existsPhone(user.getPhone(), user.getUserId())) {
            throw new IllegalArgumentException("手机号已存在");
        }

        // 如果修改了密码，需要加密
        if (StringUtils.isNotBlank(user.getUserPassword()) && 
            !user.getUserPassword().equals(existUser.getUserPassword())) {
            user.setUserPassword(passwordEncoder.encode(user.getUserPassword()));
        }

        user.setUpdateTime(LocalDateTime.now());

        return updateById(user);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteUser(Long userId) {
        if (userId == null) {
            return false;
        }
        return removeById(userId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteUsers(List<Long> userIds) {
        if (userIds == null || userIds.isEmpty()) {
            return false;
        }
        return removeByIds(userIds);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean enableUser(Long userId, boolean enabled) {
        if (userId == null) {
            return false;
        }

        SysUser user = new SysUser();
        user.setUserId(userId);
        user.setIsEnabled(enabled);
        user.setUpdateTime(LocalDateTime.now());

        return updateById(user);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean resetPassword(Long userId, String newPassword) {
        if (userId == null || StringUtils.isBlank(newPassword)) {
            return false;
        }

        SysUser user = new SysUser();
        user.setUserId(userId);
        user.setUserPassword(passwordEncoder.encode(newPassword));
        user.setUpdateTime(LocalDateTime.now());

        return updateById(user);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateLastLoginInfo(Long userId, String loginIp) {
        if (userId == null) {
            return false;
        }
        return baseMapper.updateLastLoginInfo(userId, loginIp) > 0;
    }

    @Override
    public boolean existsAccountName(String accountName, Long excludeUserId) {
        if (StringUtils.isBlank(accountName)) {
            return false;
        }

        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysUser::getAccountName, accountName);
        if (excludeUserId != null) {
            wrapper.ne(SysUser::getUserId, excludeUserId);
        }

        return count(wrapper) > 0;
    }

    @Override
    public boolean existsEmail(String email, Long excludeUserId) {
        if (StringUtils.isBlank(email)) {
            return false;
        }

        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysUser::getEmail, email);
        if (excludeUserId != null) {
            wrapper.ne(SysUser::getUserId, excludeUserId);
        }

        return count(wrapper) > 0;
    }

    @Override
    public boolean existsPhone(String phone, Long excludeUserId) {
        if (StringUtils.isBlank(phone)) {
            return false;
        }

        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysUser::getPhone, phone);
        if (excludeUserId != null) {
            wrapper.ne(SysUser::getUserId, excludeUserId);
        }

        return count(wrapper) > 0;
    }

    @Override
    public int countUsers(Boolean isEnabled) {
        return baseMapper.countUsers(isEnabled);
    }
}
